import { Link } from '@brillout/docpress'
import { ConfigSpec } from '../../components'


<ConfigSpec
  env="client"
  default={<code>false</code>}
>
```ts ts-only hide-menu
type Val = boolean | string | string[]
type KeepScrollPosition =
  | Val
  | ((pageContext: PageContextClient) => Val)
```
</ConfigSpec>

The `keepScrollPosition` setting enables you to control whether the page scrolls to the top upon navigation.

It's commonly used for nested layouts such as tabs, see <Link href="/Layout#nested" />.

For a control on a link-by-link basis, see <Link href="/clientRouting#settings">`<a href="/some-url" keep-scroll-position />`</Link>.


## Basics

By default, the page is scrolled to the top upon navigation. But if you set `keepScrollPosition` to `true` then the page's scroll position is preserved instead.

```ts
// pages/product/@id/+config.ts

import type { Config } from 'vike/types'

export default {
  // Don't scroll to top when navigating between the pages defined at pages/product/@id/**
  keepScrollPosition: true
} satisfies Config
```

```yaml
pages/product/@id/+config.ts
pages/product/@id/pricing/+Page.ts
pages/product/@id/reviews/+Page.ts
```

```yaml
# Scroll is preserved when navigating between:
/product/42
/product/42/pricing
/product/42/reviews

# Scroll is preserved when navigating between:
/product/1337
/product/1337/pricing
/product/1337/reviews
```

Note that the scroll isn't preserved (the page scrolls to the top) if the `@id` parameter differs.

```yaml
# Scroll *isn't* preserved when navigating between:
/product/42/pricing
/product/1337/pricing
```

See <Link href="#advanced" /> if this behavior doesn't fit your use case.


## Advanced

You can preserve the scroll position between any arbitrary group of pages (the "scroll group").

```ts
// /pages/product/@id/+config.ts

import type { Config } from 'vike/types'

export default {
  keepScrollPosition: 'name-of-the-scroll-group'
} satisfies Config
```

```yaml
# Scroll is preserved when navigating between:
/product/42/pricing
/product/1337/pricing
```

```ts
// /pages/reviews/@id/+config.ts

import type { Config } from 'vike/types'

export default {
  keepScrollPosition: 'name-of-the-scroll-group'
} satisfies Config
```

```yaml
# Scroll is preserved when navigating between:
/product/42
/reviews/1337
```

If two URLs belong to the same scroll group, then the scroll position is preserved.

You can also programmatically set the scroll group:

```ts
// /pages/product/@id/+keepScrollPosition.ts
// Environment: client

import type { PageContextClient } from 'vike/types'

export function keepScrollPosition(
  pageContext: PageContextClient,
  { configDefinedAt }: { configDefinedAt: string }
) {
  console.log(configDefinedAt) // /pages/product/@id/+keepScrollPosition.ts
  // This is the value Vike sets by default:
  return [configDefinedAt, pageContext.routeParams['id']]
}
```


## See also

- <Link href="/Layout#nested" />
- <Link href="/clientRouting#settings" />
- <Link href="/navigate#options" />
- <Link href="/settings" />
